#include "Core_Text_Edit.h"


Core_Text_Edit::Core_Text_Edit( QWidget * parent  )
: QTextEdit(parent), c(0)
{
    /* main window capture all */
	setAcceptDrops(false);
    setAcceptRichText(false);
    setLineWrapMode(QTextEdit::NoWrap);
    baseram = QApplication::clipboard();
    QTimer::singleShot(50, this, SLOT(initialize()));
    
}

void Core_Text_Edit::initialize()
{
QTextCursor init = textCursor();
ensureCursorVisible();
setTextCursor(init);
RebuildCompleter();
}


void Core_Text_Edit::setCompleter(QCompleter *completer)
{
    if (c)
        QObject::disconnect(c, 0, this, 0);

    c = completer;

    if (!c)
        return;

    c->setWidget(this);
    c->setCompletionMode(QCompleter::PopupCompletion);
    c->setCaseSensitivity(Qt::CaseSensitive);
    QObject::connect(c, SIGNAL(activated(const QString&)), this, SLOT(insertCompletion(const QString&)));
}


QCompleter *Core_Text_Edit::completer() const
{
    return c;
}


void Core_Text_Edit::insertCompletion( QString completion )
{
    if (c->widget() != this)
        return;
    QTextCursor tc = textCursor();
    int extra = completion.length() - c->completionPrefix().length();
    tc.movePosition(QTextCursor::Left);
    tc.movePosition(QTextCursor::EndOfWord);
    tc.insertText(completion.right(extra));
    setTextCursor(tc);
}

QString Core_Text_Edit::textUnderCursor() const
{
    QTextCursor tc = textCursor();
    tc.select(QTextCursor::WordUnderCursor);
    return tc.selectedText();
}

bool Core_Text_Edit::replace(QString text, QString reptext, QTextDocument::FindFlags flag) 
{
    
  if (textCursor().selectedText() == text) {
    QTextCursor cursor(textCursor());
    cursor.insertText(reptext);
    cursor.movePosition(QTextCursor::Left,QTextCursor::KeepAnchor,reptext.size());
    setTextCursor(cursor);
    return true;
  }
  if (find(text,flag)) {
    QTextCursor cursor(textCursor());
    cursor.insertText(reptext);
    cursor.movePosition(QTextCursor::Left,QTextCursor::KeepAnchor,reptext.size());
    setTextCursor(cursor);
    return true;
  } else
    return false;
}

void Core_Text_Edit::focusInEvent(QFocusEvent *e)
{
    if (c)
        c->setWidget(this);
    QTextEdit::focusInEvent(e);
}


void Core_Text_Edit::keyPressEvent(QKeyEvent *e)
{
m_tabSpaces = false;
CurrentCursor = textCursor();

     if (e->key() == Qt::Key_Tab) {
             LastTabCursor = textCursor();
            if (!LastTabCursor.selectedText().isEmpty()) {
                m_tabSpaces = true;
                IndentText(true);
                return;
            }
      }
      
    if (c && c->popup()->isVisible()) {
        // The following keys are forwarded by the completer to the widget
       switch (e->key()) {
       case Qt::Key_Enter:
       case Qt::Key_Return:
       case Qt::Key_Escape:
       case Qt::Key_Backtab:
            e->ignore(); 
            return; // let the completer do default behavior
       default:
           break;
       }
    }
  
  
  //////////qDebug() << "### e text " << e->text();

    bool isShortcut = ((e->modifiers() & Qt::ControlModifier) && e->key() == Qt::Key_E); // CTRL+E
    if (!c || !isShortcut) // dont process the shortcut when we have a completer
        QTextEdit::keyPressEvent(e);

    const bool ctrlOrShift = e->modifiers() & (Qt::ControlModifier | Qt::ShiftModifier);
    if (!c || (ctrlOrShift && e->text().isEmpty()))
        return;

    static QString eow("~!@#$%^&*()_+{}|:\"<>?,./;'[]\\-="); // end of word
    bool hasModifier = (e->modifiers() != Qt::NoModifier) && !ctrlOrShift;
    QString completionPrefix = textUnderCursor();

    if (!isShortcut && (hasModifier || e->text().isEmpty()|| completionPrefix.length() < 2
                      || eow.contains(e->text().right(1)))) {
        c->popup()->hide();
        return;
    }

    if (completionPrefix != c->completionPrefix()) {
        c->setCompletionPrefix(completionPrefix);
        c->popup()->setCurrentIndex(c->completionModel()->index(0, 0));
    }
  
    QRect cr = cursorRect();
    cr.setWidth(c->popup()->sizeHintForColumn(0)
                + c->popup()->verticalScrollBar()->sizeHint().width());
    c->complete(cr); // popup it up!
}



void Core_Text_Edit::IndentText( bool make )    /* make == keyPressEvent  tab + false - */
{
    /* baseram = QApplication::clipboard();   */
    QTextCursor curseurActuel = textCursor();
    QTextCursor c = textCursor();
    /* no text selection move tabulator */
    if ( make && c.selectedText().isEmpty() )
    {
        if ( m_tabSpaces )
        {
            int nbSpaces = tabStopWidth() / fontMetrics().width( " " );
            for (int i = 0; i<nbSpaces; i++)  {
                c.insertText( " " );
            }
        }
        else { 
            if ( m_tabSpaces )
            {
                int nbSpaces = tabStopWidth() / fontMetrics().width( " " );
                for (int i = 0; i<nbSpaces; i++) {
                    c.insertText( " " );
                }
            }
            else {
                c.insertText( "\t" );
            }
        }
        return;
    }  else 
           /* having text to tabulator */
          if ( make && !c.selectedText().isEmpty() ) {
    
    
          int startb = c.selectionStart();
          int endb = c.selectionEnd();
          
          c.setPosition(startb, QTextCursor::MoveAnchor);
          c.movePosition(QTextCursor::StartOfLine, QTextCursor::MoveAnchor);
          QTextBlock blocStart = c.block();

          c.setPosition(endb, QTextCursor::MoveAnchor);
          c.movePosition(QTextCursor::StartOfLine, QTextCursor::MoveAnchor);
          QTextBlock blocEnd = c.block();
          
          int position = 0;
          int startline;
          int stopline;
          int xli = 1;
          
            for ( QTextBlock block = document()->begin(); block.isValid(); block = block.next(), xli++) {
              if (blocStart.text() == block.text()) {
              startline = xli;
              }
              if (blocEnd.text() == block.text()) {
              stopline = xli;
              }
            }
            
            
            xli = 1;

                if (stopline > startline) {
                         //////qDebug() << "### ok line greats   ";
                         QString greppitxt = GrepTextLines(startline,stopline);
                         //////qDebug() << "### txt indent   " << greppitxt;
                         if (greppitxt.size() > 0) {
                         cut();
                         baseram->clear();
                         baseram->setText(greppitxt,QClipboard::Clipboard);
                         paste();
                         selectLines(startline,stopline);
                         QTextCursor c1 = textCursor();
                         c1.setPosition(c1.position() - 1 ,QTextCursor::KeepAnchor);
                         setTextCursor( c1 );
                         ensureCursorVisible();
                         }
                return;
                }  else if ( stopline == startline ) {
                        //////qDebug() << "### ok line greats   ";
                         QString greppitxto = GrepTextLines(startline,startline);
                         //////qDebug() << "### txt indent   " << greppitxt;
                         if (greppitxto.size() > 0) {
                         cut();
                         baseram->clear();
                         baseram->setText(greppitxto,QClipboard::Clipboard);
                         paste();
                         selectLines(startline,startline);
                         QTextCursor c2 = textCursor();
                         c2.setPosition(c2.position() - 1 ,QTextCursor::KeepAnchor);
                         setTextCursor( c2 );
                         ensureCursorVisible();
                         }
                    
                }
  
         }

}


void Core_Text_Edit::selectLines(int debut, int fin)    /* start end */
{
    if ( debut > fin )
        qSwap( debut, fin);
    QTextCursor c = textCursor();
    c.removeSelectedText();
    c.movePosition(QTextCursor::Start );
    c.movePosition(QTextCursor::Down, QTextCursor::MoveAnchor, debut - 1 );
    c.movePosition(QTextCursor::Down, QTextCursor::KeepAnchor, fin-debut + 1);
    setTextCursor( c );
    ensureCursorVisible();
}

QString Core_Text_Edit::GrepTextLines(int startline, int stopline )
{
QStringList  cuttextlist;
cuttextlist.clear();
int xli = 1;
for ( QTextBlock block = document()->begin(); block.isValid(); block = block.next(), xli++) {
   if (xli == startline || xli > startline) {
            if (xli == stopline || xli < stopline) {
            cuttextlist.append(GrepLineFromTxBloc(block));
            }
   }
}
return cuttextlist.join("\n");
}


QString Core_Text_Edit::GrepLineFromTxBloc( QTextBlock block )
{
        QString linetext = "";
        if ( m_tabSpaces )   /* if tabulator key on? */
        {
            int nbSpaces = tabStopWidth() / fontMetrics().width( " " );
            for (int i = 0; i<nbSpaces; i++)  {
                linetext.append( " " );
            }
            linetext.append(block.text());
          
        } else {
        linetext.append(block.text());
        }

  return linetext;
}



void Core_Text_Edit::RebuildCompleter()
{
     QString keyword = fopenutf8(WORDLIST_FILE);
     keywords.clear();
     keywords = keyword.split("\n");
     keywords.sort();
     loadwordsum = keywords.size();
     QApplication::restoreOverrideCursor();
     QStringListModel *worderlist =  new QStringListModel(keywords,this);
     completerbase = new QCompleter();
     completerbase->setModel(worderlist );
     completerbase->setModelSorting(QCompleter::CaseInsensitivelySortedModel);
     completerbase->setCaseSensitivity(Qt::CaseInsensitive);
     setCompleter(completerbase);
}


void Core_Text_Edit::AppendCurrentWord()
{
   if ( !keywords.contains(currentTXTsel) ) {
       keywords.append(currentTXTsel);
       keywords.sort();
       fwriteutf8(WORDLIST_FILE,keywords.join("\n"));
       RebuildCompleter();
   }
    
}

void Core_Text_Edit::ExportWord()
{
   bool ok;
   QString fileName = QFileDialog::getSaveFileName(this, "Export Words.",QString(setter.value("LastDir").toString()), "*.dat");
    if (fileName.size() > 1) {
        QString ultimacartellaaperta = fileName.left(fileName.lastIndexOf("/"))+"/";
         setter.setValue("LastDir",ultimacartellaaperta);  /* modus on cms not editor !!! */
            if (!fileName.endsWith(".dat")) {
            fileName = fileName+".dat"; 
            }
            Copy_To(WORDLIST_FILE,fileName);
    }
}


void Core_Text_Edit::ImportWords()
{
    bool ok;
    QString im = QFileDialog::getOpenFileName(this,tr("Import Keywords..."),QString(setter.value("LastDir").toString()),"Text file (*)");
    if (im.size() > 3) {
        
        QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
        
         QString ultimacartellaaperta = im.left(im.lastIndexOf("/"))+"/";
         setter.setValue("LastDir",ultimacartellaaperta);
         QString newkeyword = fopenutf8(im);
        
             if (newkeyword.size() < 1) {
                 QApplication::restoreOverrideCursor();
                 
              QMessageBox::information(this, tr("Error"),tr("Unable to file %1").arg(im));
              return;
             }
             QStringList ds;
             ds = newkeyword.split("\n");
             ds.sort();
             
             for (int i = 0; i < ds.size(); ++i) {
                   
                 if ( !keywords.contains(ds.at(i)) ) {
                     keywords.append(ds.at(i));
                 }
                 
             }
             keywords.sort();
             fwriteutf8(WORDLIST_FILE,keywords.join("\n"));
             RebuildCompleter();
             QApplication::restoreOverrideCursor();
    }
}


void Core_Text_Edit::contextMenuEvent( QContextMenuEvent *e )
 {
              QMenu *menu = createStandardContextMenu();
               currentTXTsel = textUnderCursor();
               if (currentTXTsel.size() > 0 && !keywords.contains(currentTXTsel)) {
               menu->addAction(tr( "Append word \"%1\" to Completion" ).arg(currentTXTsel), this , SLOT( AppendCurrentWord() ) );
               } else {
                   
                   if (currentTXTsel.size() > 0) {
                     menu->addAction(tr( "The word \"%1\" are load..." ).arg(currentTXTsel), menu , SLOT( close() ) );
                   }
                   
               }
               menu->addAction(tr( "Completion words total %1 export" ).arg(loadwordsum), this , SLOT( ExportWord() ));
               menu->addAction(tr( "Import word list from file.." ), this , SLOT( ImportWords() ) );
               menu->exec( QCursor::pos() ); 
 } 

/*
 #if defined Q_WS_MAC
 #endif
 #if defined Q_WS_WIN
 #endif
 #if defined Q_WS_X11
 #endif
*/

/* Q_ASSERT ( bool test )  */ 

/* QString one;  toLower() toUpper()  split(",")  endsWith() startsWith()  QByteArray QString::toAscii() */
/* int nummer; */ 
/* QStringList list;  join();  */ 
/* QUrl url; */ 
/* QByteArray byteArray; */ 
/* bool having; */ 
/* QDomDocument doc;*/ 
/* QDomElement root;*/ 
